#ifndef __CAPAFISICA_ARCHIVOENDISCO_H
#define __CAPAFISICA_ARCHIVOENDISCO_H

/*****************************************************************************
*                     Organizacion de Datos - 75.06                          *
*                         Catedra Lic. Servetto                              *
*            Facultad de Ingenieria - Universidad de Buenos Aires            *
******************************************************************************/ 

#include "../Comun/Archivo.h"
#include "Serializador.h"
#include "ManejadorEspacioLibre.h"
#include <string>

using namespace std;
using namespace Comun;

namespace CapaFisica
{
	
	/// Representa un IArchivo que guarda sus datos en un archivo fisico en el disco rigido.
	class ArchivoEnDisco : public IArchivo
	{
		private:
		
		bool CorroborarTamanios;
		CapaFisica::Serializador* Serializador;
		CapaFisica::ManejadorEspacioLibre* ManejadorEspacioLibre;
		
		static const int PorcentajeDeCompleto = 80;
		static const int PorcentajeDeVacio = 30;
		
		public:
		
		/// Representa a un IArchivo que guarda su informacion en archivos en disco.
		/// @param *metadatosArchivos Puntero a los metadatos que definen este archivo.
		/// @param *manejadorEspacioLibre Puntero a una intacia creada del manejador de espacio libre que utilizara este archivo.
		/// @param tamanioBloque Tamanio por defecto de los grupos del archivo.
		ArchivoEnDisco(MetadatosArchivo* metadatosArchivo, CapaFisica::ManejadorEspacioLibre* manejadorEspacioLibre, bool corroborarTamanios = false);
		
		/// Destructor por defecto del archivo en disco.
		~ArchivoEnDisco();
		
		/// Devuelve un id de grupo para ser utilizado en un grupo nuevo, ademas setea ese id al grupo pasado por parametro.
		/// @param &grupo El grupo al cual se le creara un id.
		/// @return El id del grupo recien creado.
		int CrearGrupo(Comun::Grupo &grupo);
		
		/// Guarda un grupo en el archivo en disco.
		/// @param &grupo El grupo con los datos que se guardaran en el archivo en disco.
		/// @param omitirSubflujo Desactiva el chequeo de subflujo, siver para poder grabar grupos con menos datos que un subflujo para archivos donde se corrobora el tamanio.
		/// @return Un CodigoResultado indicando el estado de la operacion de guardado.
		CodigoResultado GuardarGrupo(Comun::Grupo &grupo, bool omitirSubflujo = false);
		
		/// Leo un grupo almacenado en el archivo en disco.
		/// @param grupoId El identificador del grupo que quiero leer.
		/// @return Devuelve un grupo con todos los datos que leyo de el.
		Comun::Grupo& LeerGrupo(int grupoId);
		
		/// Borro un grupo del arhcivo en disco. Esto lo marca la lista de grupos libres para poder usar nuevamente ese grupoId en otro grupo.
		/// @param grupoId El identificador del grupo a liberar.
		void BorrarGrupo(int grupoId);
		
		/// Obtiene el primer grupoId del archivo. Util para recorridos secuenciales.
		/// @return El grupoId del primer grupo del archivo en disco.
		int PrimerGrupo();
		
		/// Obtiene el primer grupoId del archivo. Util para recorridos secuenciales.
		/// @param grupoIdActual El grupoId desde donde devolver el siguente grupoId.
		/// @return El grupoId del siguiente grupo al que posee un grupoId que se le paso por parametro.
		int SiguienteGrupo(int grupoIdActual);
		
	};
	
}

#endif
